﻿namespace NTLib.WPF.Selectors
{
    using System;
    using System.Linq;
    using System.Collections.ObjectModel;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Markup;
    using System.Collections.Generic;

    /// <summary>
    /// 
    /// </summary>
    /// <seealso cref="System.Windows.Controls.DataTemplateSelector" />
    [ContentProperty(nameof(Templates))]
    public abstract class MetaDataTemplateSelector : DataTemplateSelector
    {
        #region Fields
        #endregion

        #region Ctor

        /// <summary>
        /// Initializes a new instance of the <see cref="MetaDataTemplateSelector"/> class.
        /// </summary>
        public MetaDataTemplateSelector()
        {
            Templates = new List<SelectorDataTemplate>();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the templates.
        /// </summary>
        public List<SelectorDataTemplate> Templates { get; }

        #endregion

        #region Methods

        /// <summary>
        /// Gets the key.
        /// </summary>
        /// <returns></returns>
        protected abstract string GetKey(object item, DependencyObject container);

        /// <summary>
        /// When overridden in a derived class, returns a <see cref="T:System.Windows.DataTemplate" /> based on custom logic.
        /// </summary>
        /// <param name="item">The data object for which to select the template.</param>
        /// <param name="container">The data-bound object.</param>
        /// <returns>
        /// Returns a <see cref="T:System.Windows.DataTemplate" /> or null. The default value is null.
        /// </returns>
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var key = GetKey(item, container);
            return (from tpl in Templates
                    where string.Equals(key, tpl.Key, System.StringComparison.InvariantCultureIgnoreCase)
                    select tpl).LastOrDefault();
        }

        #endregion
    }
}
